<?php
/**
 * 数据签名认证
 * @param  array $data 被认证的数据
 * @return string       签名
 * @author 麦当苗儿 <zuojiazi@vip.qq.com>
 */
function data_auth_sign($data)
{
    //数据类型检测
    if (!is_array($data)) {
        $data = (array)$data;
    }
    ksort($data); //排序
    $code = http_build_query($data); //url编码并生成query字符串
    $sign = sha1($code); //生成签名
    return $sign;
}

/**
 * 系统加密方法
 * @param string $data 要加密的字符串
 * @param string $key 加密密钥
 * @param int $expire 过期时间 单位 秒
 * @return string
 * @author 麦当苗儿 <zuojiazi@vip.qq.com>
 */
function think_encrypt($data, $key = '', $expire = 0)
{
    $key = md5(empty($key) ? C('DATA_AUTH_KEY') : $key);
    $data = base64_encode($data);
    $x = 0;
    $len = strlen($data);
    $l = strlen($key);
    $char = '';

    for ($i = 0; $i < $len; $i++) {
        if ($x == $l) $x = 0;
        $char .= substr($key, $x, 1);
        $x++;
    }

    $str = sprintf('%010d', $expire ? $expire + time() : 0);

    for ($i = 0; $i < $len; $i++) {
        $str .= chr(ord(substr($data, $i, 1)) + (ord(substr($char, $i, 1))) % 256);
    }
    return str_replace(array('+', '/', '='), array('-', '_', ''), base64_encode($str));
}

/**
 * 系统解密方法
 * @param  string $data 要解密的字符串 （必须是think_encrypt方法加密的字符串）
 * @param  string $key 加密密钥
 * @return string
 * @author 麦当苗儿 <zuojiazi@vip.qq.com>
 */
function think_decrypt($data, $key = '')
{
    $key = md5(empty($key) ? C('DATA_AUTH_KEY') : $key);
    $data = str_replace(array('-', '_'), array('+', '/'), $data);
    $mod4 = strlen($data) % 4;
    if ($mod4) {
        $data .= substr('====', $mod4);
    }
    $data = base64_decode($data);
    $expire = substr($data, 0, 10);
    $data = substr($data, 10);

    if ($expire > 0 && $expire < time()) {
        return '';
    }
    $x = 0;
    $len = strlen($data);
    $l = strlen($key);
    $char = $str = '';

    for ($i = 0; $i < $len; $i++) {
        if ($x == $l) $x = 0;
        $char .= substr($key, $x, 1);
        $x++;
    }

    for ($i = 0; $i < $len; $i++) {
        if (ord(substr($data, $i, 1)) < ord(substr($char, $i, 1))) {
            $str .= chr((ord(substr($data, $i, 1)) + 256) - ord(substr($char, $i, 1)));
        } else {
            $str .= chr(ord(substr($data, $i, 1)) - ord(substr($char, $i, 1)));
        }
    }
    return base64_decode($str);
}

function url_compare($url, $compare, $check_param = false)
{
    $url = strtolower($url);
    $compare = strtolower($compare);
    $compare_base = preg_replace('/\?.*$/U', '', $compare);
    $auth = preg_replace('/\?.*$/U', '', $url);
    if ($check_param) {
        $query = preg_replace('/^.+\?/U', '', $url);
        $com_query = preg_replace('/^.+\?/U', '', $compare);
        parse_str($query, $param);
        parse_str($com_query, $com_param);
        $intersect = array_intersect_assoc($com_param, $param);
        if ($auth == $compare_base && $intersect == $param) {
            return true;
        }
        return false;
    } else if ($auth == $compare_base) {  //如果节点相符且url参数满足
        return true;
    }
    return false;
}

/**
 * 格式化字节大小
 * @param  number $size 字节数
 * @param  string $delimiter 数字和单位分隔符
 * @return string            格式化后的带单位的大小
 * @author 麦当苗儿 <zuojiazi@vip.qq.com>
 */
function format_bytes($size, $delimiter = '')
{
    $units = array('B', 'KB', 'MB', 'GB', 'TB', 'PB');
    for ($i = 0; $size >= 1024 && $i < 5; $i++) $size /= 1024;
    return round($size, 2) . $delimiter . $units[$i];
}

/**
 * 友好时间显示
 * @param $time
 * @return false|string
 */
function smart_time($sTime, $type = 'normal')
{
    if (!$sTime)
        return '';
    //sTime=源时间，cTime=当前时间，dTime=时间差
    $cTime = time();
    $dTime = $cTime - $sTime;
    $dDay = intval(date("z", $cTime)) - intval(date("z", $sTime));
    //$dDay     =   intval($dTime/3600/24);
    $dYear = intval(date("Y", $cTime)) - intval(date("Y", $sTime));
    //normal：n秒前，n分钟前，n小时前，日期
    if ($type == 'normal') {
        if ($dTime < 60) {
            if ($dTime < 10) {
                return '刚刚';    //by yangjs
            } else {
                return intval(floor($dTime / 10) * 10) . "秒前";
            }
        } elseif ($dTime < 3600) {
            return intval($dTime / 60) . "分钟前";
            //今天的数据.年份相同.日期相同.
        } elseif ($dYear == 0 && $dDay == 0) {
            //return intval($dTime/3600)."小时前";
            return '今天' . date('H:i', $sTime);
        } elseif ($dYear == 0) {
            return date("m月d日 H:i", $sTime);
        } else {
            return date("Y-m-d H:i", $sTime);
        }
    } elseif ($type == 'mohu') {
        if ($dTime < 60) {
            return $dTime . "秒前";
        } elseif ($dTime < 3600) {
            return intval($dTime / 60) . "分钟前";
        } elseif ($dTime >= 3600 && $dDay == 0) {
            return intval($dTime / 3600) . "小时前";
        } elseif ($dDay > 0 && $dDay <= 7) {
            return intval($dDay) . "天前";
        } elseif ($dDay > 7 && $dDay <= 30) {
            return intval($dDay / 7) . '周前';
        } elseif ($dDay > 30) {
            return intval($dDay / 30) . '个月前';
        }
        //full: Y-m-d , H:i:s
    } elseif ($type == 'full') {
        return date("Y-m-d , H:i:s", $sTime);
    } elseif ($type == 'ymd') {
        return date("Y-m-d", $sTime);
    } else {
        if ($dTime < 60) {
            return $dTime . "秒前";
        } elseif ($dTime < 3600) {
            return intval($dTime / 60) . "分钟前";
        } elseif ($dTime >= 3600 && $dDay == 0) {
            return intval($dTime / 3600) . "小时前";
        } elseif ($dYear == 0) {
            return date("Y-m-d H:i:s", $sTime);
        } else {
            return date("Y-m-d H:i:s", $sTime);
        }
    }
}

/**
 * 字符串截取，支持中文和其他编码
 * @static
 * @access public
 * @param string $str 需要转换的字符串
 * @param string $start 开始位置
 * @param string $length 截取长度
 * @param string $charset 编码格式
 * @param string $suffix 截断显示字符
 * @return string
 */
function msubstr($str, $start = 0, $length, $charset = "utf-8", $suffix = true)
{
    if (function_exists("mb_substr"))
        $slice = mb_substr($str, $start, $length, $charset);
    elseif (function_exists('iconv_substr')) {
        $slice = iconv_substr($str, $start, $length, $charset);
        if (false === $slice) {
            $slice = '';
        }
    } else {
        $re['utf-8'] = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/";
        $re['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/";
        $re['gbk'] = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/";
        $re['big5'] = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/";
        preg_match_all($re[$charset], $str, $match);
        $slice = join("", array_slice($match[0], $start, $length));
    }
    return $suffix ? $slice . '...' : $slice;
}

function subtext($text, $length)
{
    if(mb_strlen($text, 'utf8') > $length) {
        return mb_substr($text, 0, $length, 'utf8').'...';
    } else {
        return $text;
    }

}
function get_me($field = 'id') {
    $row = D('Common/User')->getMe();
    if($field) return $row[$field];
    return $row;
}
/**
 * 钩子注册快捷方法
 * @param $tag
 * @param $name
 */
function hook_add($tag, $name)
{
    Think\Hook::add($tag, $name);
}

/**
 * 钩子批量注册快捷方法
 * @param $data
 * @param bool $recursive
 */
function hook_import($data, $recursive = true)
{
    Think\Hook::import($data, $recursive);
}

/**
 * 入口构造 控制器访问url
 * 遵循系统框架的U函数使用规则
 * @param string $url
 * @param string $entry 入口文件 默认为addon.php
 * @param string $vars
 * @param bool $suffix
 * @param bool $domain
 * @return mixed
 */
function entry_url($url = '', $entry = 'index.php', $vars = '', $suffix = true, $domain = false)
{
    $url = U($url, $vars, $suffix, $domain);
    $re = str_replace(basename(PHP_FILE), $entry, PHP_FILE);
    return str_replace(PHP_FILE, $re, $url);
}

/**
 * 主程序url
 * @param $url
 * @param string $vars
 * @param bool $suffix
 * @param bool $domain
 * @return mixed
 */
function main_url($url, $vars = '', $suffix = true, $domain = false)
{
    $entry_file = 'index.php';
    return entry_url($url, $entry_file, $vars, $suffix, $domain);
}


/**
 * api通信链接
 * @param string $url
 * @param string $vars
 * @param bool $suffix
 * @param bool $domain
 * @return string
 */
function U2Encrypt($url = '', $vars = '', $filter='U')
{
    $query = $vars;
    if (is_string($vars)) {
        parse_str($vars, $query);
    }
    $params = array(
        C('API_KEY') => think_encrypt(http_build_query($query)),
    );
    if(!function_exists($filter)) {
        $filter = 'U';
    }
    return $filter($url, $params, true, true);
}

/**
 * 插件url
 * @param $url
 * @param string $vars
 * @param bool $suffix
 * @param bool $domain
 * @return mixed
 */
function addon_url($url, $vars = '', $suffix = true, $domain = false)
{
    $entry_file = 'addon.php';
    return entry_url($url, $entry_file, $vars, $suffix, $domain);
}

/**
 * 来自W方法
 * 渲染输出Widget
 * @param string $name Widget名称
 * @param array $data 传入的参数
 * @return void
 */
function Widget($name, $data=array()) {
    // 改用变量方法执行 2019 02 12 改
    // 为了防止实例缓存影响 保证每个W方法的变量都是独立的 取消A方法的调用
    $info   =   pathinfo($name);
    $action =   $info['basename'];
    $module =   $info['dirname'];
    $layer  =   'Widget';
    $level  =   $layer == C('DEFAULT_C_LAYER')?C('CONTROLLER_LEVEL'):1;
    $class  =   parse_res_name($module,$layer,$level);
    if(class_exists($class)) {
        $class =   new $class();
        if($class){
            if(is_string($data)) {
                parse_str($data,$data);
            }
            return $class->{$action.C('ACTION_SUFFIX')}($data);
        }
    }else {
        return false;
    }
}